package com.gitee.booting.balancer4j;

import lombok.Data;
import lombok.experimental.Accessors;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

@Data
@Accessors(fluent = true, chain = true)
public class Candidate<T, R> {
    private final T instance;
    private final Map<String, Object> meta = new HashMap<>();

    private Candidate(T instance) {
        this.instance = instance;
    }

    /**
     * Processes the message exchange.
     * <p/>
     * If there was a failure processing then the caused {@link Exception} would be set on the {@link Action}.
     *
     * @param action   the message exchange
     * @param callback the {@link Callback} will be invoked when the processing of the exchange is completed.
     *                 If the exchange is completed synchronously, then the callback is also invoked synchronously.
     *                 The callback should therefore be careful of starting recursive loop.
     * @return (doneSync) <tt>true</tt> to continue execute synchronously, <tt>false</tt> to continue being executed asynchronously
     */
    boolean process(Action<Candidate<T, R>, R> action, Callback callback) {
        callback.done(action.what().apply(this));
        return true;
    }

    public static <T, R> Candidate<T, R> of(T instance, Function<T, Map<String, Object>>... functions) {
        Candidate<T, R> candidate = new Candidate<>(instance);
        for (Function<T, Map<String, Object>> function : functions)
            candidate.meta.putAll(function.apply(instance));
        return candidate;
    }
}
